<?php

declare(strict_types=1);

define('APP_ROOT', dirname(__DIR__));

// 启用会话（用于 CSRF、登录会话等）
if (session_status() !== PHP_SESSION_ACTIVE) {
    session_start();
}

// 简单 PSR-4 风格自动加载（App\* -> app/*）
spl_autoload_register(function ($class) {
    $prefix = 'App\\';
    $baseDir = APP_ROOT . '/app/';
    $len = strlen($prefix);
    if (strncmp($prefix, $class, $len) !== 0) {
        return;
    }
    $relative = substr($class, $len);
    $file = $baseDir . str_replace('\\', '/', $relative) . '.php';
    if (is_file($file)) {
        require $file;
    }
});

require_once APP_ROOT . '/app/Core/Router.php';

use App\Core\Router;
use App\Core\Config;
use App\Core\ErrorHandler;
use App\Core\AccessLogger;
use App\Core\Session;
use App\Core\RateLimit;

// 预加载环境配置
Config::load();

// 配置安全会话
Session::configure();

// 加载限速数据
RateLimit::load();

// 注册全局错误处理（基于 APP_DEBUG）
$debug = strtolower(App\Core\Config::get('APP_DEBUG', 'false') ?? 'false') === 'true';
ErrorHandler::register($debug);

// 启动访问日志计时
AccessLogger::start();

// 注册路由
require APP_ROOT . '/routes/web.php';

// 解析请求
$method = $_SERVER['REQUEST_METHOD'] ?? 'GET';
$uri = parse_url($_SERVER['REQUEST_URI'] ?? '/', PHP_URL_PATH) ?: '/';

// 如部署于子目录，可按需去除基路径
// $basePath = rtrim(dirname($_SERVER['SCRIPT_NAME']), '/\\');
// if ($basePath && $basePath !== '/') {
//     $uri = preg_replace('#^' . preg_quote($basePath, '#') . '#', '', $uri);
//     $uri = $uri === '' ? '/' : $uri;
// }

[$handler, $params] = Router::match($method, $uri);

if ($handler === null) {
    AccessLogger::log($method, $uri, 404);
    // 使用自定义 404 页面
    http_response_code(404);
    $root = APP_ROOT;
    $errorFile = $root . '/templates/errors/404.php';
    if (file_exists($errorFile)) {
        include $errorFile;
    } else {
        echo '404 Not Found';
    }
    exit;
}

if (is_callable($handler)) {
    echo call_user_func_array($handler, $params);
    AccessLogger::log($method, $uri, http_response_code());
    exit;
}

if (is_string($handler)) {
    // 形如 "HomeController@index"
    [$controller, $action] = array_pad(explode('@', $handler, 2), 2, 'index');
    $fqcn = 'App\\Controllers\\' . $controller;
    if (!class_exists($fqcn)) {
        http_response_code(500);
        AccessLogger::log($method, $uri, 500);
        echo "Controller $fqcn not found";
        exit;
    }
    $instance = new $fqcn();
    if (!method_exists($instance, $action)) {
        http_response_code(500);
        AccessLogger::log($method, $uri, 500);
        echo "Action $action not found in $fqcn";
        exit;
    }
    echo call_user_func_array([$instance, $action], $params);
    AccessLogger::log($method, $uri, http_response_code());
    exit;
}

http_response_code(500);
AccessLogger::log($method, $uri, 500);
echo 'Invalid route handler';
